<script setup lang="ts">
import { ref, watch } from 'vue';
import type { Dayjs } from 'dayjs';
import dayjs from 'dayjs';
import { message } from 'ant-design-vue';
import { updateSceneApi, updateSceneCoverApi } from '@/api/MicroScene/MicroSceneApi';
import type { AreaScene } from '@/types/micro-scene';
import type { UploadFile, UploadProps } from 'ant-design-vue';
import { UploadOutlined } from '@ant-design/icons-vue';

const props = defineProps<{
  open: boolean;
  scene?: AreaScene;
}>();

// 定义Modal的两个事件：
// 1. 改变Modal的打开状态事件
// 2. 更新场景信息成功事件
const emit = defineEmits<{
  (e: 'changeOpenState', openState: boolean): void;
  (e: 'success'): void;
}>();

const formState = ref({
  title: '',
  tags: [] as string[],
  achievement: [] as string[],
  reward: [] as string[],
  timeRange: [] as Dayjs[],
});

const imageUrl = ref<string>('');
const fileList = ref<UploadFile[]>([]);

// 监听scene变化，更新表单数据
watch(
  () => props.scene,
  (newScene) => {
    if (newScene) {
      formState.value = {
        title: newScene.sceneTitle,
        tags: newScene.tags,
        achievement: newScene.achievement,
        reward: newScene.reward.split('+'),
        timeRange: [
          dayjs(newScene.startTime.split('T')[0]),
          dayjs(newScene.endTime.split('T')[0]),
        ],
      };
      imageUrl.value = newScene.coverUrl;
    }
  },
  { immediate: true },
);

const rules = {
  title: [{ required: true, message: '请输入标题' }],
  tags: [{ required: true, message: '请至少输入一个标签' }],
  achievement: [{ required: true, message: '请至少输入一个成果' }],
  reward: [{ required: true, message: '请至少输入一个奖励' }],
  timeRange: [{ required: true, message: '请选择起止时间' }],
};

const beforeUpload: UploadProps['beforeUpload'] = (file) => {
  // 检查文件类型
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  if (!isJpgOrPng) {
    message.error('只能上传 JPG/PNG 格式的图片！');
    return false;
  }

  // 检查文件大小
  const isLt2M = file?.size ? file.size / 1024 / 1024 < 2 : false;
  if (!isLt2M) {
    message.error('图片大小不能超过 2MB！');
    return false;
  }

  // 更新文件列表
  fileList.value = [file];

  // 创建本地预览
  const reader = new FileReader();
  reader.addEventListener('load', () => {
    imageUrl.value = reader.result as string;
  });
  reader.readAsDataURL(file);

  return false;
};

const handleOk = async () => {
  try {
    if (!props.scene)
      return;

    const startTime = formState.value.timeRange[0].format('YYYY-MM-DD');
    const endTime = formState.value.timeRange[1].format('YYYY-MM-DD');

    // 更新基本信息
    await updateSceneApi(
      Number(props.scene.sceneId),
      formState.value.title,
      formState.value.reward.join('+'),
      formState.value.tags.join(','),
      formState.value.achievement.join(','),
      props.scene.areaId.toString(),
      startTime,
      endTime,
    );

    // 如果有新上传的图片，则更新封面
    if (fileList.value[0]) {
      await updateSceneCoverApi(
        Number(props.scene.sceneId),
        Number(props.scene.areaId),
        fileList.value[0].originFileObj as File,
      );
    }

    message.success('更新成功');
    // 触发两个事件
    emit('changeOpenState', false);
    emit('success');
  }
  catch (error: any) {
    message.error(`更新失败：${error.message}`);
  }
};

const handleCancel = () => {
  emit('changeOpenState', false);
};
</script>

<template>
  <a-modal
    :open="open"
    title="编辑微场景"
    :mask-closable="false"
    @ok="handleOk"
    @cancel="handleCancel"
  >
    <a-form :model="formState" layout="vertical">
      <div style="display: flex; align-items: flex-start; gap: 1rem;">
        <a-form-item>
          <a-upload
            v-model:file-list="fileList"
            list-type="picture-card"
            :show-upload-list="false"
            :before-upload="beforeUpload"
            :multiple="false"
            :max-count="1"
          >
            <img
              v-if="imageUrl"
              :src="imageUrl"
              alt="封面"
              style="width: 95%; height: 95%; object-fit: cover;"
            >
            <div v-else>
              <UploadOutlined />
              <div style="margin-top: 0.5rem;">
                上传封面图
              </div>
            </div>
          </a-upload>
        </a-form-item>

        <div style="flex: 1;">
          <a-form-item
            name="title"
            :rules="rules.title"
          >
            <a-input v-model:value="formState.title" placeholder="请输入标题" />
          </a-form-item>

          <a-form-item
            name="tags"
            :rules="rules.tags"
          >
            <a-select
              v-model:value="formState.tags"
              mode="tags"
              :open="false"
              placeholder="标签，输入后按回车键添加"
              style="width: 100%;"
              :token-separators="[',']"
            />
          </a-form-item>
        </div>
      </div>

      <a-form-item
        name="achievement"
        :rules="rules.achievement"
      >
        <a-select
          v-model:value="formState.achievement"
          mode="tags"
          :open="false"
          placeholder="成果，输入后按回车键添加"
          style="width: 100%;"
          :token-separators="[',']"
        />
      </a-form-item>

      <a-form-item
        name="reward"
        :rules="rules.reward"
      >
        <a-select
          v-model:value="formState.reward"
          mode="tags"
          :open="false"
          placeholder="奖励，输入后按回车键添加"
          style="width: 100%;"
          :token-separators="[',']"
        />
      </a-form-item>

      <a-form-item
        name="timeRange"
        :rules="rules.timeRange"
      >
        <a-range-picker
          v-model:value="formState.timeRange"
          style="width: 100%;"
          format="YYYY-MM-DD"
        />
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<style scoped>
.ant-form-item {
  margin-bottom: 0.5rem;
}
</style>
